﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using PasteCodeTaskBase;
using PasteTimer.taskmodels;

namespace PasteTimer
{
    /// <summary>
    /// 
    /// </summary>
    public class ReportHandler : IPasteCodeTaskBase
    {
        private IAppCache _cache;
        private IServiceProvider _serviceProvider;
        private readonly TaskConfig _config;
        private ILogger<ReportHandler> _logger;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="cache"></param>
        /// <param name="serviceProvider"></param>
        /// <param name="config"></param>
        /// <param name="logger"></param>
        public ReportHandler(
            IAppCache cache,
            IServiceProvider serviceProvider,
            IOptions<TaskConfig> config,
            ILogger<ReportHandler> logger)
        {
            _cache = cache;
            _serviceProvider = serviceProvider;
            _logger = logger;
            _config = config.Value;

        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override string LocationTickRegex()
        {
            return "(.*):00:01";
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override bool IsLocationService()
        {
            return _config.SingleModel;
        }

        private int _lasthourdate = -1;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="date"></param>
        /// <param name="datestring"></param>
        private async Task<bool> BuildReport(DateTime date, string datestring)
        {
            ////如何判断 收集上个月 收集昨天 上级上一个小时

            //收集上一个小时

            //收集昨天

            //收集上个月

            var list = new List<ReportInfo>();
            int.TryParse(datestring, out var dateint);
            var dicsun = await _cache.HashGetAllAsync(PublicString.CollectHashKey);
            if (dicsun != null && dicsun.Count > 0)
            {
                var removelist = new List<string>();
                foreach (var ii in dicsun)
                {
                    if (ii.Key.Contains(":"))
                    {
                        var splits = ii.Key.Split(':');
                        if (splits.Length == 3)
                        {
                            int.TryParse(splits[0], out var time);
                            int.TryParse(splits[1], out var taskid);
                            var state = splits[2];
                            if (time < dateint)
                            {
                                removelist.Add(ii.Key);//历史时间的数据给删除
                            }
                            else
                            {
                                if (time == dateint)
                                {
                                    //统计
                                    var find = list.Where(x => x.NodeId == taskid).FirstOrDefault();
                                    if (find == null || find == default)
                                    {
                                        find = new ReportInfo();
                                        find.DataDate = date;
                                        find.NodeId = taskid;
                                        find.DataType = 0;
                                        list.Add(find);
                                    }
                                    switch (state)
                                    {
                                        case "okay": { find.Success = ii.Value; } break;
                                        case "fail": { find.Failed = ii.Value; } break;
                                        case "run": { find.Total = ii.Value; } break;
                                        default: break;
                                    }
                                    removelist.Add(ii.Key);//当前统计了的也准备删除
                                }
                            }
                        }
                    }
                }
                foreach (var idel in removelist)
                {
                    _cache.HashDeleteAsync(PublicString.CollectHashKey, idel);
                }
            }

            if (list.Count > 0)
            {
                //准备入库
                using var _scope = _serviceProvider.CreateScope();
                using var _dbContext = _scope.ServiceProvider.GetRequiredService<IPasteTimerDbContext>();
                _dbContext.AddRange(list);
                await _dbContext.SaveChangesAsync();
                _dbContext.Dispose();
                _scope.Dispose();
            }
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        public override void Dispose()
        {
            base.Dispose();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public override async Task<PasteTaskCallBackModel> Work(PasteTaskSharedModel info)
        {
            try
            {
                var nowdate = DateTime.Now;
                var prewdate = nowdate.AddMinutes(-5);
                var ddate = DateTime.Parse(prewdate.ToString("yyyy-MM-dd HH:00:00"));
                var lasthour = nowdate.AddMinutes(-5).ToString("yyyyMMddHH");
                //var lasthour = nowdate.ToString("yyyyMMddHH");
                if (_lasthourdate != -1)
                {
                    if (_lasthourdate != nowdate.Hour)
                    {
                        await BuildReport(ddate, lasthour);
                    }
                }
                else
                {
                    await BuildReport(ddate, lasthour);
                }
                _lasthourdate = nowdate.Hour;
            }
            catch (Exception exl)
            {
                //stopwatch.Stop();
                _logger.LogException(exl);
                return new PasteTaskCallBackModel() { code = 500, message = exl.Message };
            }
            //stopwatch.Stop();
            return new PasteTaskCallBackModel() { code = 200, message = "执行成功" };
        }
    }
}
